#coding=utf-8
'''
Created on 2010-10-12
@author: lxd
'''
import wx
import time
import threading
import win32gui, win32api, win32con
time_interval = 0.01

def getLogger():     
    import logging
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    #create console handler and set level to info
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    #create file handler and set level to debug
    fh = logging.FileHandler('log.log', 'w')
    fh.setLevel(logging.DEBUG)
    #create formatter
    formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s')
    #add formatter to ch and fh
    ch.setFormatter(formatter)
    fh.setFormatter(formatter)
    #add ch and fh to logger
    logger.addHandler(ch)
    logger.addHandler(fh)
    return logger   

log = getLogger()

class Operate():
    def click(self, handle, pos):
        client_pos = win32gui.ScreenToClient(handle, pos)
        tmp = win32api.MAKELONG(client_pos[0], client_pos[1])
        win32gui.SendMessage(handle, win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0)
        win32api.SendMessage(handle, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, tmp) 
        win32api.SendMessage(handle, win32con.WM_LBUTTONUP, win32con.MK_LBUTTON, tmp)
    
    def get_curpos(self):
        #获得当前鼠标位置
        return win32gui.GetCursorPos()
    
    def get_win_handle(self, pos):
        #获得指定位置窗口：
        return win32gui.WindowFromPoint(pos)

class WorkThread(threading.Thread):
    def __init__(self, operate, pos, handle):
        threading.Thread.__init__(self)
        self.timeToQuit = threading.Event()
        self.timeToQuit.clear()
        self.operate = operate
        self.pos = pos
        self.handle = handle
        
    def stop(self):
        self.timeToQuit.set()

    def run(self):
        while True:
            if not self.timeToQuit.isSet():
                self.operate.click(self.handle, self.pos)  
                log.info('click:[%s]%s' % (str(self.handle), str(self.pos)))
                time.sleep(time_interval)
            else:
                log.info('quit')
                break
                        
class FrameWithHotKey(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.regHotKey()
        self.Bind(wx.EVT_HOTKEY, self.OnHotKeyStart, id=self.hotKeyId_start)
        self.Bind(wx.EVT_HOTKEY, self.OnHotKeyEnd, id=self.hotKeyId_end)
        self.Bind(wx.EVT_HOTKEY, self.OnHotKeyQuit, id=self.hotKeyId_quit)
        self.work = None
        self.operate = Operate()
        log.info(u'使用方法：')
        log.info(u'Alt+F1:连续点击')
        log.info(u'Alt+F2:停止点击')
        log.info(u'Alt+F3:关闭')
        
    def regHotKey(self):
        self.hotKeyId_start = 100
        self.RegisterHotKey(self.hotKeyId_start, win32con.MOD_ALT, win32con.VK_F1)
        self.hotKeyId_end = 101
        self.RegisterHotKey(self.hotKeyId_end, win32con.MOD_ALT, win32con.VK_F2)
        self.hotKeyId_quit = 102
        self.RegisterHotKey(self.hotKeyId_quit, win32con.MOD_ALT, win32con.VK_F3)
                
    def OnHotKeyStart(self, evt):
        if not self.work:
            pos = self.operate.get_curpos() 
            handle = self.operate.get_win_handle(pos)  
            self.work = WorkThread(self.operate, pos, handle)
            self.work.setDaemon(True) 
            self.work.start()
            
    def OnHotKeyEnd(self, evt):
        if self.work:
            self.work.stop()
            self.work = None
            
    def OnHotKeyQuit(self, evt):
        exit()
        
app = wx.App()
FrameWithHotKey(None)
app.MainLoop()
